<template>
    <div style="height: 100%;">
        <el-input v-model="filterText" size="small" :placeholder="placeholder" clearable style="margin-bottom:10px;width:90%" />
        <el-tree ref="organizationTree"
                 :node-key="nodekey"
                 :data="organizationUnits"
                 :props="defaultProps"
                 :filter-node-method="filterNode"
                 :expand-on-click-node="expandOnClickNode"
                 draggable
                 highlight-current
                 :allow-drop="allowDrop"
                 :allow-drag="allowDrag"
                 :default-expand-all="expandAll"
                 :default-expanded-keys="expandKeys"
                 @node-expand="handleExpand"
                 @node-contextmenu="handleContextmenu "
                 @node-collapse="handleClose"
                 @node-drag-start="handleDragStart"
                 @node-drag-enter="handleDragEnter"
                 @node-drag-leave="handleDragLeave"
                 @node-drag-over="handleDragOver"
                 @node-drag-end="handleDragEnd"
                 @node-click="handleNodeClick"
                 @node-drop="handleDrop">
            <span slot-scope="scope" class="custom-tree-node">
                <!-- <el-tooltip class="item" effect="dark" :open-delay="500" :content="scope.data.orgCode" placement="bottom-end"> -->
                <span>
                    <i :class="scope.node.expanded ? 'el-icon-folder-opened' : 'el-icon-folder'" />
                    <span class="vice-node"> {{ scope.data[showLabelName] }}</span>
                    <span v-if="showDesc !== '' && scope.data[showDesc]" class="vice-node">({{ scope.data[showDesc] }})</span>
                    <!--<span v-show="showNumber && scope.data.NUMBER" class="vice-node" style="font-size: 12px;font-weight: 600;">（{{ scope.data.NUMBER }}人）</span>-->
                    <el-dropdown v-show="showMenu" trigger="hover" placement="bottom-start" size="medium" @command="handleCommand">
                        <span class="el-dropdown-link"><i class="el-icon-caret-bottom" /></span>
                        <el-dropdown-menu slot="dropdown">
                            <el-dropdown-item v-for="(item,index) in treeMenus"
                                              v-show="showMenuItem(scope, item)" 
                                              :key="index"
                                              :command="{command:item.value,data:scope}">
                                {{ item.label }}
                            </el-dropdown-item>
                        </el-dropdown-menu>
                    </el-dropdown>
                </span>
                <!-- </el-tooltip> -->
            </span>
        </el-tree>
    </div>
</template>
<script>
    export default {
        name: 'OrganizationTree',
        props: {
            data: { type: Array, default: null },
            hasChildCanAdd: { type: Boolean, default: false },
            treeMenus: { type: Array, default: null },
            orgData: { type: Array, default: null },
            expandAll: { type: Boolean, default: false },
            expandOnClickNode: { type: Boolean, default: true },
            placeholder: { type: String, default: '输入节点名称进行过滤' },
            nodekey: { type: String, default: 'id' },
            parentKey: { type: String, default: 'parentID' },
            showLabelName: { type: String, default: 'name' },
            showDesc: { type: String, default: '' },
            showMenu: { type: Boolean, default: true },
            showNumber: { type: Boolean, default: false },
            ifDraggable: { type: Boolean, default: false },
            expandKeysArr: { type: Array, default: null },
            allowDropType: { type: Number, default: 0, }
        },
        data() {
            return {
                filterText: '',
                organizationUnits: [],
                defaultProps: {
                    children: 'children',
                    label: 'displayName'
                },
                expandKeys: [],
            };
        },
        watch: {
            expandKeysArr(val) {
                this.expandKeys.push.apply(this.expandKeys, this.expandKeysArr);
            },
            data(val) {
                this.organizationUnits = this.toTree(val, null);
            },
            filterText(val) {
                this.$refs.organizationTree.filter(val);
            },
            orgData(val) {
                this.organizationUnits = this.orgData;
            }
        },
        mounted() { },
        methods: {
            getAllNodes(node = [], arr = []) {
                for (let item of node) {
                    arr.push(item);
                    let parentArr = [];
                    if (item.children) parentArr.push(...item.children);
                    if (parentArr && parentArr.length) this.getAllNodes(parentArr, arr);
                };
                return arr
            },
            toTree(nodeList, parentID) {
                var nodes = nodeList.filter(item => { return item[this.parentKey] === parentID });
                if (nodes.length > 0) {
                    nodes.forEach(item => {
                        if (item[this.nodekey]) {
                            var children = this.toTree(nodeList, item[this.nodekey]);
                            item.children = children;
                        };
                    });
                };
                return nodes;
            },
            // 展开节点
            handleExpand(data, node, row) {
                //this.expandKeys.push(data[this.nodekey]);
                if (row.expanded === false) {
                    var items = [];
                    items.push(data);
                    this.getAllNodes(items).forEach(x => {
                        this.expandKeys.push(x[this.nodekey]);
                    });
                };
                this.$emit('handleExpand', data);
            },
            handleClose(data, node, row) {
                var items = [];
                items.push(data);
                this.getAllNodes(items).forEach(x => {
                    this.expandKeys.splice(this.expandKeys.findIndex(x => x === data[this.nodekey]), 1);
                });
                this.$emit('handleClose', data);
            },
            handleCommand(obj) {
                this.$emit('command', obj);
            },
            filterNode(value, data) {
                if (!value) return true;
                return data[this.showLabelName].indexOf(value) !== -1;
            },
            handleNodeClick(data, node, row) {
                // 不适用于点击节点后,其下所有子节点全部展开时
                //const nodeData = this.$refs.organizationTree.getNode(data);
                //if (nodeData.expanded) {
                //    console.log("节点已展开");
                //} else {
                //    console.log("节点未展开");
                //}
                this.$emit('node-click', data);
            },
            handleContextmenu(event, data, node, row) {
                if (row.expanded === false) {
                    var items = [];
                    items.push(data);
                    this.getAllNodes(items).forEach(x => {
                        this.expandKeys.push(x[this.nodekey]);
                    });
                };
            },
            handleDragStart(node, ev) {
                this.$emit('node-drag-start', node);
            },
            handleDragEnter(draggingNode, dropNode, ev) {
                this.$emit('node-drag-enter', draggingNode, dropNode, ev);
            },
            handleDragLeave(draggingNode, dropNode, ev) {
                this.$emit('node-drag-leave', draggingNode, dropNode, ev);
            },
            handleDragOver(draggingNode, dropNode, ev) {
                this.$emit('node-drag-over', draggingNode, dropNode, ev);
            },
            handleDragEnd(draggingNode, dropNode, dropType, ev) {
                if (dropType !== 'none') {
                    var ter = this.getAllNodes(this.organizationUnits);
                    this.$emit('node-drag-end', draggingNode, dropNode, dropType, ter);
                }
                //this.$emit('node-drag-end', draggingNode, dropNode, dropType, ev);
                //console.log('tree drag end: ', dropNode && dropNode.label, dropType);
            },
            handleDrop(draggingNode, dropNode, dropType, ev) {
                this.$emit('node-drop', draggingNode, dropNode, dropType, ev);
                if (this.expandKeys.findIndex(x => x === dropNode.data.beTypeID) === -1 && dropType === 'inner') {
                    this.expandKeys.push(dropNode.data.beTypeID);
                }
            },
            allowDrop(draggingNode, dropNode, type) {
                if (this.allowDropType === 0) { // 拖动无限制
                    return true;
                } else if (this.allowDropType === 1) { // 同级别节点拖动
                    if (type != 'inner') {
                        if (!!draggingNode.data.parentID && !!dropNode.data.parentID && dropNode.data.parentID === draggingNode.data.parentID) {  //拖动节点和目标节点都是子节点
                            return true;
                        } else if (!draggingNode.data.parentID && !dropNode.data.parentID) { //拖动节点和目标节点都是父节点
                            return true;
                        }
                    }
                }
                // 拖动目标节点
                // 不允许拖动到目标节点内,只允许下方,上方
                //if (type != 'inner') {
                //    if (!!draggingNode.data.parentID) {
                //        if (dropNode.data.parentID === draggingNode.data.parentID) {
                //            return true;
                //        }
                //    } else {
                //        if (!dropNode.data.parentID) {
                //            return true;
                //        };
                //    }
                //}
            },
            allowDrag(draggingNode) {
                if (this.ifDraggable) {
                    return true;
                } else {
                    return false;
                }
            },
            showMenuItem(scope, item) {
                if (item.isShow === false) {
                    return false
                } else {
                    if (this.allowDropType === 1) {
                        if (item.value === 'createAdd') {
                            return scope.data.parentID === null ? true : false;
                        } else {
                            return !!scope.data.parentID ? true : false;
                        };
                    } else {
                        return (item.value === 'addUser' || item.value === 'addRole') && (scope.data.children.length > 0 && !this.hasChildCanAdd) ? false : true;
                    }
                }
            }
        },
        template: '#template'
    };
</script>
